home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / C_WINDOW.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-19  |  17.7 KB  |  715 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <memory.h>
  11. #include "XA_TYPES.H"
  12. #include "XA_DEFS.H"
  13. #include "XA_GLOBL.H"
  14. #include "STD_WIDG.H"
  15. #include "BOX3D.H"
  16. #include "C_WINDOW.H"
  17. #include "RECTLIST.H"
  18. #include "MESSAGES.H"
  19. #include "OBJECTS.H"
  20. #include "RESOURCE.H"
  21. #include "SYSTEM.H"
  22. #include "DESKTOP.H"
  23. #include "graf_mou.h"
  24.  
  25. /*
  26.     Low-level Window Stack Management Functions
  27. */
  28.  
  29. XA_WINDOW *window_list=NULL;        /* The global system window stack */
  30. short wind_handle=0;                /* Window handle counter (used to generate unique window handles)
  31.                                        As this loops round, there may be a problem if a user opens
  32.                                        more than 32767 windows in one session :) */
  33.  
  34. /*
  35.      Create a window
  36. */
  37. XA_WINDOW *create_window(short pid, long tp, short rx, short ry, short rw, short rh)
  38. {
  39.     XA_WINDOW *nw=(XA_WINDOW *)malloc(sizeof(XA_WINDOW));
  40.  
  41.     DIAGS(("create_window()\n"));
  42.  
  43.     if (!nw)            /* Unable to allocate memory for window? */
  44.         return NULL;
  45.  
  46.     nw->x=rx;
  47.     nw->y=ry;
  48.     nw->w=rw;
  49.     nw->h=rh;
  50.     nw->prev_x=rx;
  51.     nw->prev_y=ry;
  52.     nw->prev_w=rw;
  53.     nw->prev_h=rh;
  54.     nw->handle=wind_handle++;
  55.     nw->owner=pid;
  56.     nw->is_open=FALSE;
  57.     nw->rect_user=nw->rect_list=nw->rect_start=NULL;
  58.     nw->redraw=NULL;
  59.     nw->destructor=NULL;
  60.     nw->keypress=NULL;
  61.     nw->window_status=XAWS_CLOSED;
  62.     
  63.     DIAGS((" allocated:handle=%d\n",nw->handle));
  64.     
  65.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  66.     
  67.     if (root_window)    /* Append window to back of window list, behind the root window (if it exists) */
  68.     {
  69.         DIAGS((" inserted behind root window\n"));
  70.         nw->prev=root_window;
  71.         nw->next=root_window->next;
  72.         if (root_window->next)
  73.             root_window->next->prev=nw;
  74.         root_window->next=nw;
  75.     }else{
  76.         DIAGS((" no root, initial window created\n"));
  77.         nw->next=NULL;
  78.         nw->prev=NULL;
  79.         window_list=nw;
  80.     }
  81.     
  82.     Psemaphore(3,WIN_LIST_SEMAPHORE,0);
  83.     
  84.     standard_widgets(nw,tp);    /* Attatch the appropriate widgets to the window */
  85.  
  86.     if (tp&STORE_BACK)            /* If STORE_BACK extended attribute is used, window preserves it's own background */
  87.     {
  88.         DIAGS((" allocating background storage buffer\n"));
  89.         nw->background=(void*)malloc(display.planes*((rw+35)>>2)*(rh+20));
  90.         nw->bgx=-1;
  91.     }else{
  92.         nw->background=NULL;
  93.     }
  94.  
  95.     calc_work_area(nw);            /* Calculate an initial work area */
  96.  
  97.     return nw;
  98. }
  99.  
  100. /*
  101.     Display a window
  102. */
  103. void display_window(XA_WINDOW *wind)
  104. {
  105.     short f,pnt[8],x,y,w,h;
  106.     WidgetCallback wc;
  107.  
  108.     DIAGS(("display_window(handle=%d)\n",wind->handle));
  109.  
  110.     if ((window_list==wind)&&(wind->active_widgets&STORE_BACK))    /* Is this a 'preserve own background' window? */
  111.     {
  112.         MFDB Mscreen;
  113.         MFDB Mpreserve;
  114.         
  115.         pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w; pnt[3]=wind->y+wind->h;
  116.         pnt[4]=0; pnt[5]=0; pnt[6]=wind->w; pnt[7]=wind->h;
  117.         
  118.         Mpreserve.fd_w=wind->w+20;
  119.         Mpreserve.fd_h=wind->h+20;
  120.         Mpreserve.fd_wdwidth=(Mpreserve.fd_w+15)>>4;
  121.         Mpreserve.fd_nplanes=display.planes;
  122.         Mpreserve.fd_stand=0;
  123.         Mpreserve.fd_addr=wind->background;
  124.  
  125.         Mscreen.fd_addr=NULL;
  126.  
  127.         v_hide_c(V_handle);
  128.         vro_cpyfm(V_handle, S_ONLY, pnt, &Mscreen, &Mpreserve);
  129.         v_show_c(V_handle,1);
  130.         
  131.         wind->bgx=wind->x; wind->bgy=wind->y;
  132.     }else{
  133.         wind->bgx=-1;
  134.     }
  135.     
  136.     x=wind->wx;
  137.     y=wind->wy;
  138.     w=wind->ww;
  139.     h=wind->wh;
  140.     
  141. /* Display the window backdrop (borders only, GEM style) */
  142.     vsf_color(V_handle,display.dial_colours.bg_col);
  143.     vsf_interior(V_handle,FIS_SOLID);
  144.     if (wind->active_widgets&NO_WORK)
  145.     {
  146.         pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=wind->y+wind->h-SHADOW_OFFSET;
  147.         v_bar(V_handle,pnt);
  148.     }else{
  149.         pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=y;
  150.         v_bar(V_handle,pnt);
  151.         pnt[1]=y+h; pnt[3]=wind->y+wind->h-SHADOW_OFFSET;
  152.         v_bar(V_handle,pnt);
  153.         pnt[0]=wind->x; pnt[1]=wind->y; pnt[2]=x;
  154.         v_bar(V_handle,pnt);
  155.         pnt[0]=x+w; pnt[2]=wind->x+wind->w-SHADOW_OFFSET;
  156.         v_bar(V_handle,pnt);
  157.     }
  158.  
  159. /* Display drop shadow  */
  160.     vsf_color(V_handle,display.dial_colours.border_col);
  161.     pnt[0]=wind->x+wind->w-SHADOW_OFFSET+1; pnt[1]=wind->y+SHADOW_OFFSET; pnt[2]=wind->x+wind->w-1; pnt[3]=wind->y+wind->h-1;
  162.     v_bar(V_handle,pnt);
  163.     pnt[0]=wind->x+SHADOW_OFFSET-1; pnt[1]=wind->y+wind->h-SHADOW_OFFSET+1; pnt[2]=wind->x+wind->w-SHADOW_OFFSET; pnt[3]=wind->y+wind->h-1;
  164.     v_bar(V_handle,pnt);
  165.  
  166. /* Display the work area */
  167.     if (!(wind->active_widgets&NO_WORK))
  168.     {
  169.         vsl_color(V_handle,display.dial_colours.b_r_col);
  170.  
  171.         pnt[0]=x; pnt[1]=y+h;
  172.         pnt[2]=x; pnt[3]=y;
  173.         pnt[4]=x+w; pnt[5]=y;
  174.         v_pline(V_handle,3,pnt);
  175.     
  176.         pnt[0]=x+2; pnt[1]=y+h-1;
  177.         pnt[2]=x+w-1; pnt[3]=y+h-1;
  178.         pnt[4]=x+w-1; pnt[5]=y+1;
  179.         v_pline(V_handle,3,pnt);
  180.     
  181.         vsl_color(V_handle,display.dial_colours.t_l_col);
  182.  
  183.         pnt[0]=x+w; pnt[1]=y+1;
  184.         pnt[2]=x+w; pnt[3]=y+h;
  185.         pnt[4]=x+1; pnt[5]=y+h;
  186.         v_pline(V_handle,3,pnt);
  187.     
  188.         pnt[0]=x+1; pnt[1]=y+h-1;
  189.         pnt[2]=x+1; pnt[3]=y+1;
  190.         pnt[4]=x+w-1; pnt[5]=y+1;
  191.         v_pline(V_handle,3,pnt);
  192.     }
  193.  
  194. /* Go through and display the window widgets using their display behaviour */
  195.     if (wind->window_status==XAWS_ICONIFIED)
  196.     {
  197.         wc=wind->widgets[XAW_TITLE].behaviour[XACB_DISPLAY];
  198.         (*wc)(wind, &(wind->widgets[XAW_TITLE]));
  199.         wc=wind->widgets[XAW_ICONIFY].behaviour[XACB_DISPLAY];
  200.         (*wc)(wind, &(wind->widgets[XAW_ICONIFY]));
  201.     }else{
  202.         for(f=0; f<XA_MAX_WIDGETS; f++)
  203.         {
  204.             wc=wind->widgets[f].behaviour[XACB_DISPLAY];
  205.             if (wc)
  206.                 (*wc)(wind, &(wind->widgets[f]));
  207.         }
  208.     }
  209.  
  210. /* If the window has an auto-redraw function, call it */
  211.     if (wind->redraw)
  212.     {
  213.         (*(wind->redraw))(wind);
  214.     }
  215.  
  216. }
  217.  
  218. XA_WINDOW *wind_find(short x, short y)
  219. {
  220.     XA_WINDOW *w=window_list;
  221.  
  222.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  223.     
  224.     while(w)
  225.     {
  226.         if ((w->is_open)&&((((x>=w->x)&&(y>=w->y))&&(x<w->x+w->w))&&(y<w->y+w->h)))
  227.         {
  228.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  229.             return w;
  230.         }
  231.         w=w->next;
  232.     }
  233.     
  234.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  235.     
  236.     return NULL;
  237. }
  238.     
  239.  
  240. XA_WINDOW *get_wind_by_handle(short h)
  241. {
  242.     XA_WINDOW *w;
  243.  
  244.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  245.     
  246.     w=window_list;
  247.     
  248.     while(w)
  249.     {
  250.         if (w->handle==h)
  251.         {
  252.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  253.             return w;
  254.         }
  255.         w=w->next;
  256.     }
  257.     
  258.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  259.     
  260.     return NULL;
  261. }
  262.  
  263. /*
  264.     Pull this window to the head of the window list
  265. */
  266. void pull_wind_to_top(XA_WINDOW *w)
  267. {
  268.     XA_CLIENT *owner;
  269.     XA_WINDOW *wl=w->prev;
  270.     GRECT clip,r;
  271.     DIAGS(("pull_wind_to_top(%d)\n",w->handle));
  272.  
  273.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  274.  
  275.     if (window_list->owner!=w->owner)    /* If we're getting a new top window, we may need */
  276.     {                                    /* to swap menu bars..... */
  277.         XA_WIDGET_TREE *menu_bar;
  278.  
  279.         Psemaphore(2,ROOT_SEMAPHORE,-1L);
  280.  
  281.         menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
  282.  
  283.         owner=Pid2Client(w->owner);
  284.         menu_bar->tree=owner->std_menu;
  285.         menu_bar->owner=w->owner;
  286.  
  287.         if ((owner->desktop)                    /* Change desktops? */
  288.             &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
  289.         {
  290.             set_desktop(owner->desktop);
  291.             root_window->owner=w->owner;;
  292.  
  293.             v_hide_c(V_handle);
  294.             display_non_topped_window(root_window,NULL);
  295.             v_show_c(V_handle,1);
  296.         }else{                                            /* No - just change menu bars */
  297.             rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
  298.  
  299.             clip.g_w=root_window->widgets[XAW_MENU].w;
  300.             clip.g_h=root_window->widgets[XAW_MENU].h;
  301.  
  302.             v_hide_c(V_handle);
  303.             display_non_topped_window(root_window,&clip);
  304.             v_show_c(V_handle,1);
  305.         }
  306.  
  307.         Psemaphore(3,ROOT_SEMAPHORE,0L);
  308.     }
  309.  
  310.     wl=w->prev;
  311.  
  312.     r.g_x=w->x;    r.g_y=w->y;
  313.     r.g_w=w->w;    r.g_h=w->h;
  314.  
  315.     if (w->prev)
  316.     {
  317.         w->prev->next=w->next;
  318.     }else{
  319.         window_list=w->next;
  320.     }
  321.     if (w->next)
  322.         w->next->prev=w->prev;
  323.     w->next=window_list;
  324.     if (window_list) window_list->prev=w;
  325.     w->prev=NULL;
  326.     window_list=w;
  327.  
  328.     while(wl)
  329.     {
  330.             DIAGS(("candidate window=%d\n",wl->handle));
  331.         clip.g_x=wl->x;    clip.g_y=wl->y;
  332.         clip.g_w=wl->w;    clip.g_h=wl->h;
  333.         if (rc_intersect(&r,&clip))
  334.         {
  335.                 DIAGS(("  - regenerate rect_list for %d\n",wl->handle));
  336.             generate_rect_list(wl);
  337.         }
  338.         wl=wl->prev;
  339.     }
  340.  
  341.     generate_rect_list(w);
  342.  
  343.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  344.  
  345. }
  346.  
  347. void send_wind_to_bottom(XA_WINDOW *w)
  348. {
  349.     XA_WINDOW *old_top=window_list,*wl=w->next;
  350.     GRECT r,clip;
  351.     
  352.     if (w->next==root_window) return;            /* Can't send to the bottom a window that's already there */
  353.     
  354.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  355.     
  356.     if (w==window_list)                    /* If this window was on top, change window list */
  357.         window_list=w->next;
  358.     
  359.     if (w->next)                        /* Remove window from window list */
  360.         w->next->prev=w->prev;
  361.     
  362.     if (w->prev)
  363.         w->prev->next=w->next;
  364.         
  365.     w->prev=root_window->prev;
  366.     w->next=root_window;
  367.     
  368.     if (w->prev)                        /* root window is always at the bottom */
  369.     {
  370.         w->prev->next=w;
  371.     }else{
  372.         window_list=w;                    /* window is still on top (must be the only window */
  373.     }
  374.  
  375.     root_window->prev=w;
  376.  
  377.     if (window_list==old_top)            /* If no change in top window, we can return here */
  378.     {
  379.         Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  380.         return;
  381.     }
  382.  
  383.     r.g_x=w->x;    r.g_y=w->y;
  384.     r.g_w=w->w;    r.g_h=w->h;
  385.     
  386.     while(wl!=root_window->next)
  387.     {
  388.         clip.g_x=wl->x;    clip.g_y=wl->y;
  389.         clip.g_w=wl->w;    clip.g_h=wl->h;
  390.         if (rc_intersect(&r,&clip))
  391.             generate_rect_list(wl);
  392.         wl=wl->next;
  393.     }
  394.  
  395.     generate_rect_list(w);
  396.     
  397.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  398.  
  399.     if (old_top->owner!=window_list->owner)    /* If we're getting a new top window, we may need */
  400.     {                                        /* to swap menu bars..... */
  401.         XA_WIDGET_TREE *menu_bar=(XA_WIDGET_TREE*)(root_window->widgets[XAW_MENU].stuff);
  402.         XA_CLIENT *owner;
  403.     
  404.         Psemaphore(2,ROOT_SEMAPHORE,-1L);
  405.             
  406.         owner=Pid2Client(window_list->owner);
  407.         menu_bar->tree=owner->std_menu;
  408.         menu_bar->owner=window_list->owner;
  409.  
  410.         if (owner->desktop                    /* Change desktops? */
  411.             &&((owner->desktop!=desktop)&&(owner->desktop!=ResourceTree(system_resources,DEF_DESKTOP))))
  412.         {
  413.             set_desktop(owner->desktop);
  414.             root_window->owner=window_list->owner;
  415.  
  416.             v_hide_c(V_handle);
  417.             display_non_topped_window(root_window,NULL);
  418.             v_show_c(V_handle,1);
  419.         }else{                                            /* No - just change menu bars */
  420.             rp_2_ap(root_window, root_window->widgets+XAW_MENU, &clip.g_x, &clip.g_y);
  421.         
  422.             clip.g_w=root_window->widgets[XAW_MENU].w;
  423.             clip.g_h=root_window->widgets[XAW_MENU].h;
  424.  
  425.             v_hide_c(V_handle);
  426.             display_non_topped_window(root_window,&clip);
  427.             v_show_c(V_handle,1);
  428.         }
  429.  
  430.         Psemaphore(3,ROOT_SEMAPHORE,0L);
  431.     }    
  432. }
  433.  
  434. /*
  435.     Change an open window's coordinates, updating rectangle lists as appropriate
  436. */
  437. void move_window(XA_WINDOW *wind,short x,short y,short w,short h)
  438. {
  439.     XA_WINDOW *wl;
  440.     XA_RECT_LIST *rl=rect_get_system_first(wind);
  441.     GRECT r_wind_old,r_wind_new,clip;
  442.     short blit_mode,coords[8];
  443.     MFDB Mscreen;
  444.  
  445.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  446.  
  447.     wind->prev_x=wind->x;                /* Save windows previous coords */
  448.     wind->prev_y=wind->y;
  449.     wind->prev_w=wind->w;
  450.     wind->prev_h=wind->h;
  451.  
  452.     r_wind_old.g_x=wind->x; r_wind_old.g_y=wind->y;
  453.     r_wind_old.g_w=wind->w; r_wind_old.g_h=wind->h;
  454.             
  455.     wind->x=x;                            /* Change the window coords */
  456.     wind->y=y;
  457.     wind->w=w;
  458.     wind->h=h;
  459.     
  460.     blit_mode=((wind==window_list)
  461.                 &&((wind->prev_x+wind->prev_w<display.w)&&(wind->prev_y+wind->prev_h<display.h))
  462.                 &&((x+w<display.w)&&(y+h<display.h))
  463.                 &&((wind->prev_w==w)&&(wind->prev_h==h)));
  464.  
  465.     calc_work_area(wind);                /* Recalculate the work area (as well as moving, */
  466.                                         /* it might have changed size). */
  467.  
  468.     generate_rect_list(wind);            /* update the window's rectangle list, it will be out of date now */
  469.     
  470.     v_hide_c(V_handle);
  471.     
  472.     clear_clip();
  473.     
  474.     if (blit_mode)    /* If window is being blit mode transferred, do the blit instead of redrawing */
  475.     {
  476.         Mscreen.fd_addr=NULL;
  477.         coords[0]=wind->prev_x; coords[1]=wind->prev_y;
  478.         coords[2]=wind->prev_x+wind->prev_w-1; coords[3]=wind->prev_y+wind->prev_h-1;
  479.         coords[4]=x; coords[5]=y;
  480.         coords[6]=x+w-1; coords[7]=y+w-1;
  481.  
  482.         vro_cpyfm(V_handle, S_ONLY, coords, &Mscreen, &Mscreen);
  483.     }else{
  484.         display_non_topped_window(wind,NULL);
  485.         if (!(wind->active_widgets&NO_MESSAGES))    /* does this window's application want messages? if so send it a redraw */
  486.             send_app_message(wind->owner, WM_REDRAW, 0, wind->handle, wind->wx, wind->wy, wind->ww, wind->wh);
  487.     }
  488.  
  489.     for(wl=wind->next; wl!=root_window->next; wl=wl->next)
  490.     {
  491.         clip.g_x=wl->x; clip.g_y=wl->y;
  492.         clip.g_w=wl->w; clip.g_h=wl->h;
  493.                 
  494.         if (rc_intersect(&r_wind_old,&clip))        /* Check for newly exposed windows */
  495.         {
  496.  
  497.             generate_rect_list(wl);
  498.             display_non_topped_window(wl,&clip);
  499.             if (!(wl->active_widgets&NO_MESSAGES))    /* does this window's application want messages? if so send it a redraw */
  500.                 send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  501.  
  502.         }else{
  503.  
  504.             clip.g_x=wl->x; clip.g_y=wl->y;
  505.             clip.g_w=wl->w; clip.g_h=wl->h;
  506.             if (rc_intersect(&r_wind_new,&clip))    /* Check for newly covered windows */
  507.                 generate_rect_list(wl);                /* We don't need to send a redraw to these windows, we just have to update their rect lists */
  508.         
  509.         }
  510.     }
  511.     
  512.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  513.  
  514.     v_show_c(V_handle,1);
  515. }
  516.  
  517.  
  518. /*
  519.     Close an open window and re-display any windows underneath
  520.     it. Also places window behind root window but does NOT delete it - the window
  521.     will still exist after this call.
  522. */
  523. short close_window(XA_WINDOW *wind)
  524. {
  525.     XA_WINDOW *wl;
  526.     GRECT r,clip;
  527.     XA_CLIENT *client;
  528.     short is_top;
  529.     
  530.     if (wind==NULL)
  531.     {
  532.         DIAGS(("WARNING:close_window:Invalid window pointer\n"));
  533.         return 0;            /* Invalid window handle, return error */
  534.     }
  535.  
  536.     if (wind->is_open==FALSE)
  537.         return 0;
  538.     
  539.     is_top=(wind==window_list);
  540.  
  541.     wl=wind->next;
  542.  
  543.     r.g_x=wind->x;    r.g_y=wind->y;
  544.     r.g_w=wind->w;    r.g_h=wind->h;
  545.  
  546.     wind->is_open=FALSE;                    /* tag window as closed */
  547.     wind->window_status=XAWS_CLOSED;
  548.  
  549.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  550.  
  551.     if (wind->prev)                        /* Remove the window from the window list */
  552.         wind->prev->next=wind->next;
  553.     
  554.     if (wind->next)
  555.         wind->next->prev=wind->prev;
  556.     
  557.     wind->next=root_window->next;            /* Keep closed windows on the other side of the root window */
  558.     wind->prev=root_window;
  559.     if (root_window->next)
  560.         root_window->next->prev=wind;
  561.     root_window->next=wind;
  562.  
  563.     if (is_top)
  564.          window_list=wl;
  565.  
  566.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  567.  
  568.     v_hide_c(V_handle);
  569.                                         /* Redisplay any windows below the one we are closing */
  570.     while(wl!=wind)
  571.     {
  572.         clip.g_x=wl->x;    clip.g_y=wl->y;
  573.         clip.g_w=wl->w;    clip.g_h=wl->h;
  574.         if (rc_intersect(&r,&clip))
  575.         {
  576.             generate_rect_list(wl);
  577.             display_non_topped_window(wl, &clip);
  578.             if (!(wl->active_widgets&NO_MESSAGES))    /* does this window's application want messages? if so send it a redraw */
  579.                 send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  580.         }
  581.         wl=wl->next;
  582.     }
  583.  
  584.     if ((is_top)&&(window_list!=root_window))    /* New top window should be displayed in it's entirety */
  585.     {
  586.         display_non_topped_window(window_list, NULL);
  587.         if(!(window_list->active_widgets&NO_MESSAGES))
  588.         {
  589.             send_app_message(window_list->owner, WM_ONTOP, 0, window_list->handle, 0, 0, 0, 0);
  590.             send_app_message(window_list->owner, WM_REDRAW, 0, window_list->handle, r.g_x, r.g_y, r.g_w, r.g_h);
  591.         }
  592.     }
  593.  
  594.     v_show_c(V_handle,1);
  595.     
  596.     client=Pid2Client(window_list->owner);
  597.     /* New top window - change the cursor to this clients choice */
  598.     graf_mouse(client->client_mouse, client->client_mouse_form);
  599.  
  600.     return 1;
  601. }
  602.  
  603. void delete_window(XA_WINDOW *wind)
  604. {
  605.     if (!wind) return;
  606.  
  607.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  608.  
  609.     if (wind->destructor)
  610.         (*(wind->destructor))(wind);    /* Call the window destructor if any */
  611.     
  612.     if (wind==window_list)
  613.         window_list=wind->next;
  614.  
  615.     if (wind->prev) wind->prev->next=wind->next;
  616.     if (wind->next) wind->next->prev=wind->prev;
  617.  
  618.     if (wind->background)
  619.         free(wind->background);
  620.     
  621.     if (wind->rect_start)
  622.         free(wind->rect_start);
  623.     
  624.     Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  625.  
  626.     free(wind);
  627. }
  628.  
  629. /*
  630.     Display a window that isn't on top, respecting clipping
  631.     - pass clip==NULL to redraw whole window, otherwise clip is a pointer to a GRECT that
  632.     defines the clip rectangle.
  633. */
  634. void display_non_topped_window(XA_WINDOW *w,GRECT *clip)
  635. {
  636.     GRECT target;
  637.     XA_RECT_LIST *rl=rect_get_system_first(w);
  638.  
  639.     if (w==window_list)
  640.     {
  641.         set_clip(display.x, display.y, display.w, display.h);
  642.         display_window(w);
  643.         return;
  644.     }
  645.  
  646.     if (w->is_open)
  647.     {
  648.         while(rl)
  649.         {            
  650.             if (clip)
  651.             {
  652.                 target.g_x=rl->x;
  653.                 target.g_y=rl->y;
  654.                 target.g_w=rl->w;
  655.                 target.g_h=rl->h;
  656.                 
  657.                 if (rc_intersect(clip,&target))
  658.                 {
  659.                     set_clip(target.g_x, target.g_y, target.g_w, target.g_h);
  660.                     display_window(w);
  661.                 }
  662.             }else{
  663.                 set_clip(rl->x, rl->y, rl->w, rl->h);
  664.                 display_window(w);
  665.             }
  666.             rl=rect_get_system_next(w);
  667.         }
  668.     }
  669.     clear_clip();
  670. }
  671.  
  672. /*
  673.     Display windows below a given rectangle, starting with window w.
  674. */
  675. void display_windows_below(GRECT *r, XA_WINDOW *w)
  676. {
  677.     GRECT win_r;
  678.     XA_WINDOW *wl;
  679.     XA_RECT_LIST *rl;
  680.  
  681.     for(wl=w; wl!=root_window->next; wl=wl->next)
  682.     {                                            
  683.  
  684.         if (wl->is_open)
  685.         {
  686.             for(rl=rect_get_system_first(wl); rl; rl=rect_get_system_next(wl))
  687.             {                    
  688.                 win_r.g_x=rl->x;
  689.                 win_r.g_y=rl->y;
  690.                 win_r.g_w=rl->w;
  691.                 win_r.g_h=rl->h;
  692.                     
  693.                 if (rc_intersect(r, &win_r))
  694.                 {
  695.                     set_clip(win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
  696.  
  697.                     display_window(wl);                /* Display the window */
  698.                             
  699.                                             /* send a redraw message to the owner of the window for this rectangle */
  700.                     if (!(wl->active_widgets&NO_REDRAWS))
  701.                     {
  702.                         send_app_message(window_list->owner, WM_ONTOP, 0, window_list->handle, 0, 0, 0, 0);
  703.                         send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, win_r.g_x, win_r.g_y, win_r.g_w, win_r.g_h);
  704.                     }
  705.                 }
  706.  
  707.             }
  708.         
  709.         }
  710.     }
  711.     
  712.     clear_clip();
  713.  
  714. }
  715.